package com.dingyx.ps.util;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.ArrayUtils;
import sun.misc.BASE64Decoder;
import sun.security.rsa.RSAPrivateKeyImpl;
import sun.security.util.DerValue;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;

public class EncryptUtil {

	/**
	 * RSA分段加密
	 * @param input
	 * @param rsaPublicKey
	 * @return
	 */
	public static String rsaEncrypt(String input, String rsaPublicKey) {
		String result = "";
		try {
			// 将Base64编码后的公钥转换成PublicKey对象
			byte[] buffer = Base64.decodeBase64(rsaPublicKey);
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
			PublicKey publicKey = keyFactory.generatePublic(keySpec);
			// 加密
			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.ENCRYPT_MODE, publicKey);
			byte[] inputArray = input.getBytes();
			int inputLength = inputArray.length;
			System.out.println("加密字节数：" + inputLength);
			// 最大加密字节数，超出最大字节数需要分组加密
			int MAX_ENCRYPT_BLOCK = 117;
			// 标识
			int offSet = 0;
			byte[] resultBytes = {};
			byte[] cache = {};
			while (inputLength - offSet > 0) {
				if (inputLength - offSet > MAX_ENCRYPT_BLOCK) {
					cache = cipher.doFinal(inputArray, offSet, MAX_ENCRYPT_BLOCK);
					offSet += MAX_ENCRYPT_BLOCK;
				} else {
					cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
					offSet = inputLength;
				}
				resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
				System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
			}
			result = Base64.encodeBase64String(resultBytes);
		} catch (Exception e) {
			System.out.println("rsaEncrypt error:" + e.getMessage());
		}
		System.out.println("加密的结果：" + result);
		return result;
	}

	/**
	 * RSA分段解密
	 * @param data
	 * @param privateKey
	 * @return
	 */
	public static String rsaDecrypt(String data,String privateKey) throws Exception {
		BASE64Decoder base64Decoder = new BASE64Decoder();
		byte[] desEncodeRead = base64Decoder.decodeBuffer(privateKey);//
		DerValue d = new DerValue(desEncodeRead);
		RSAPrivateKey priKey= (RSAPrivateKey) RSAPrivateKeyImpl.parseKey(d);
		Cipher cipher =Cipher.getInstance("RSA/ECB/PKCS1Padding");
		cipher.init(Cipher.DECRYPT_MODE, priKey);
		byte[] src = base64Decoder.decodeBuffer(data);
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		for(int i=0; i<src.length; i+= 128){
			byte[] toDecodeSegment = ArrayUtils.subarray(src, i,i+128);
			byte[] destByte = cipher.doFinal(toDecodeSegment);
			System.out.println("decode"+destByte.length);
			out.write(destByte);
		}
		byte[] decode = out.toByteArray();
		return new String(decode, "UTF-8");
	}


}